package main

import (
	"fmt"
)

type A struct {
	Name string
	age  int
}

// 大写
func (a *A) SayOk() {
	fmt.Println("A SayOk", a.Name)
}

// 小写
func (a *A) hello() {
	fmt.Println("A hello", a.Name)
}

type B struct {
	A
	Name string
}

func (b *B) SayOk() {
	fmt.Println("B SayOk", b.Name)
}

func main() {
	var b1 B
	// 结构体可以使用嵌套匿名结构体所有的字段和方法，即：首字母大写或者小写的字段、方法，都可以使用。
	b1.A.Name = "tom"
	b1.A.age = 19
	b1.A.SayOk()
	b1.A.hello()

	// 上面的写法可以简化，省略匿名结构体A
	b1.Name = "smith"
	b1.age = 20
	b1.SayOk()
	b1.hello()

	// 当结构体和匿名结构体有相同的字段或者方法时，编译器采用就近访问原则访问，如希望访问匿名结构体的字段和方法，可以通过匿名结构体名来区分
	var b B
	b.Name = "jack"    // 就近原则，访问的是 B 结构体的 Name 字段
	b.A.Name = "scott" // 明确指定访问 A 匿名结构体的字段 Name
	b.age = 100
	b.SayOk()   // 就近原则，访问的是 B 结构体的 SayOk 方法
	b.A.SayOk() // 明确指定访问 A 匿名结构体的 SayOk 方法
	b.hello()
}
